/*
 * GPUC
 * 
 * Copyright © 2008 Attila T. Áfra <attila.afra@gmail.com>
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "Common.hpp"
#include "Uncopyable.hpp"
#include "Exception.hpp"

/*------------------------------------------------------------------------------------------------*/

namespace GPUC
{
    enum BufferUsage
    {
        BufferUsage_Upload   = GPUC_BufferUsage_Upload,
        BufferUsage_Download = GPUC_BufferUsage_Download
    };

    class Buffer : Uncopyable
    {
    public:
        Buffer(size_t size, BufferUsage usage);
        ~Buffer();

        GPUC_Buffer getObject() const;
        size_t getSize() const;

        void* map(Access access);
        void unmap();

    private:
        GPUC_Buffer buffer;
    };
}

/*------------------------------------------------------------------------------------------------*/

GPUC::Buffer::Buffer(size_t size, GPUC::BufferUsage usage)
{
    buffer = GPUC_Buffer_create(size, static_cast<GPUC_BufferUsage>(usage));
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

GPUC::Buffer::~Buffer()
{
    GPUC_Buffer_destroy(buffer);
}

/*------------------------------------------------------------------------------------------------*/

GPUC_Buffer GPUC::Buffer::getObject() const
{
    return buffer;
}

/*------------------------------------------------------------------------------------------------*/

size_t GPUC::Buffer::getSize() const
{
    return GPUC_Buffer_getSize(buffer);
}

/*------------------------------------------------------------------------------------------------*/

void* GPUC::Buffer::map(GPUC::Access access)
{
    void* data = GPUC_Buffer_map(buffer, static_cast<GPUC_Access>(access));
    Internal::checkError();
    return data;
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::Buffer::unmap()
{
    GPUC_Buffer_unmap(buffer);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/
